package com.nononsenseapps.feeder.ui.reader

import android.annotation.SuppressLint
import android.app.Activity
import android.app.Application
import android.graphics.Point
import androidx.fragment.app.Fragment
import androidx.lifecycle.*
import androidx.lifecycle.viewmodel.CreationExtras
import com.nononsenseapps.feeder.db.ARG
import com.nononsenseapps.feeder.db.UIState
import com.nononsenseapps.feeder.db.entity.FeedItemFeature
import com.nononsenseapps.feeder.db.room.*
import com.nononsenseapps.feeder.ui.R
import com.nononsenseapps.feeder.db.view.PreviewItem
import com.nononsenseapps.feeder.processor.interceptor.formatBodyText
import com.nononsenseapps.feeder.ui.base.CoroutineScopedFragmentViewModel
import com.nononsenseapps.feeder.util.NlpUtils
import com.nononsenseapps.feeder.util.PrefUtils
import com.nononsenseapps.feeder.util.TabletUtils
import com.gitee.wsl.android.store.statehandle.saveAble
import com.nononsenseapps.feeder.ui.base.CoroutineScopedViewModel
import com.nononsenseapps.feeder.worker.loadHtmlPage
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import timber.log.Timber
import java.util.*

class FeedItemViewModel( application: Application,private val state: SavedStateHandle) :  CoroutineScopedViewModel(application) {

   // val feedItemDao = AppDatabase.getInstance(application).feedItemDao()
    val feedItemFeatureDao=AppDatabase.getInstance(application).feedItemFeatureDao()

    private val itemUpdate = MutableStateFlow(false)
    private val _liveItemFlow = MutableStateFlow(FeedItemWithFeed())
    val liveItemFlow = _liveItemFlow.combine(itemUpdate) { loveItem, _ -> loveItem }

    var isNotification = false

    private var notificationItemId = ID_UNSET

    var feedItemFeature: FeedItemFeature?=null

    val similarityItems = mutableListOf<PreviewItem>()

    var readLastScrollLine by state.saveAble(UIState.FeedItemReader.READER_LAST_SCROLL_POSITION,0)

    private val allowDownload by lazy{ PrefUtils.shouldLoadImages(application)}

    init {
        state.get<Long>(ARG.FEED_ITEM_ID)?.let{
            _updateItem(it)
        }
    }

    fun notificationRead(itemId: Long){
        isNotification=true
        notificationItemId=itemId
        Timber.d("notificationRead itemId:$itemId")
        updateItem(itemId)
    }

    fun currentItemId():Long=_liveItemFlow.value.id

    private fun _updateItem(id: Long){
        viewModelScope.launch(Dispatchers.IO) {
            val rssItem = feedItemDao.loadFeedItemWithFeed(id)
            rssItem.feature?.let { featureId ->
                feedItemFeature = feedItemFeatureDao.get(featureId)
            }
            _liveItemFlow.value=rssItem
        }
    }

    fun updateItem(id: Long){
        state[ARG.FEED_ITEM_ID]=id
        readLastScrollLine=0
        checkSimilarityItems(id)
        _updateItem(id)
    }

    @SuppressLint("NullSafeMutableLiveData")
    fun clearCache(){
        Timber.d("clear view model cache start...")
        feedItemFeature = null
        Timber.d("clear view model cache end....")
    }

    fun getLiveItemDescription(id: Long):String{
        return feedItemDao.loadFeedItemWithFeed(id).description
    }

    fun getItemDao():FeedItemDao=feedItemDao

    fun checkSimilarityItems(itemId: Long){
       similarityItems.clear()
    }

    fun listItemFeatureList() : Flow<List<PreviewItem>> {
        return feedItemDao.loadLivePreviewsWithFeatureFlow(feedItemFeature!!.id)
    }

    fun getCurrentFeedItem(): FeedItemWithFeed {
       return _liveItemFlow.value
    }

    fun tranLanguage(from: Locale, to: Locale){
        viewModelScope.launch(Dispatchers.IO) {
            val item= _liveItemFlow.value
            //_liveItemFlow.value = FeedItemWithFeed(id=-1,title="tran running...",description = "tran running...")
            NlpUtils.tranLanguage(from,to,item.description).let{tranStr->
                item.title=NlpUtils.tranLanguage(from,to,item.title)
                item.description = tranStr
                itemUpdate.value=!itemUpdate.value
            }
        }
    }

    fun loadFullText(){
        viewModelScope.launch(Dispatchers.IO) {
            val item= _liveItemFlow.value
            item.link?.let { link ->
                loadHtmlPage(link)?.let { tranStr->
                    item.description = tranStr
                    feedItemDao.loadFullPageText(item.id,tranStr)
                    itemUpdate.value=!itemUpdate.value
                }
            }
        }
    }

    fun formatBody(){
        viewModelScope.launch(Dispatchers.IO) {
            val item = _liveItemFlow.value
            formatBodyText(item.description,item.id).let{tranStr->
                item.description = tranStr
                itemUpdate.value=!itemUpdate.value
            }
        }
    }
}

/*
class FeedItemViewModelFactory() : ViewModelProvider.NewInstanceFactory() {
    @Suppress("UNCHECKED_CAST")
    override fun <T : ViewModel> create(modelClass: Class<T>, extras: CreationExtras): T {
        val application = checkNotNull(extras[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY])
        return FeedItemViewModel(application,extras.createSavedStateHandle()) as T
    }
}

fun Fragment.getFeedItemViewModel(): FeedItemViewModel {
    val factory = FeedItemViewModelFactory()
    return ViewModelProvider(this, factory)[FeedItemViewModel::class.java]
}
*/

internal fun Activity.maxImageSize(): Point {
    val size = Point()
    windowManager?.defaultDisplay?.getSize(size)
    if (TabletUtils.isTablet(this)) {
        // Using twice window height since we do scroll vertically
        size.set(Math.round(resources.getDimension(R.dimen.reader_tablet_width)), 2 * size.y)
    } else {
        // Base it on window size
        size.set(size.x - 2 * Math.round(resources.getDimension(R.dimen.keyline_1)), 2 * size.y)
    }

    return size
}
